<template>
  <BasicModal
    @register="registerModal"
    :title="title"
    :width="modalWidth"
    :confirmLoading="confirmLoading"
    okText="开始生成"
    cancelText="取消"
    @ok="onSubmit"
    @cancel="onCancel"
  >
    <a-spin :spinning="confirmLoading">
      <BasicForm @register="registerForm" />
      <a-card key="0" title="子表信息" size="small" v-if="showSubTable">
        <JVxeTable ref="subTableRef" :columns="subTable.columns" :dataSource="subTable.dataSource" rowNumber :maxHeight="580" />
      </a-card>
    </a-spin>
  </BasicModal>
  <file-select-modal @register="registerFileSelectModal" @select="onFileSelect" />
  <code-file-list-modal @register="registerCodeFileListModal" />
</template>
<script lang="ts">
  import { useMessage } from '/@/hooks/web/useMessage';
  import { defineComponent, ref, computed, reactive, nextTick } from 'vue';
  import { defHttp } from '/@/utils/http/axios';
  import { BasicForm, useForm } from '/@/components/Form';
  import { BasicModal, useModalInner, useModal } from '/@/components/Modal';
  import { JVxeTypes } from '/@/components/jeecg/JVxeTable/types';
  import { useCodeGeneratorFormSchemas } from '../use/useSchemas.js';
  import { underLine2CamelCase } from '/@/utils/common/compUtils';
  import CodeFileListModal from './CodeFileListModal.vue';
  import FileSelectModal from './FileSelectModal.vue';

  export default defineComponent({
    name: 'CodeGenerator',
    components: { BasicForm, BasicModal, FileSelectModal, CodeFileListModal },
    emits: ['register'],
    setup(props) {
      const { createMessage: $message } = useMessage();
      const JEECG_ONL_PROJECT_PATH = 'JEECG_ONL_PROJECT_PATH';
      const single = ref(true);
      const subTableRef = ref();
      const modalWidth = computed(() => (single.value ? 800 : 1200));
      const title = ref('代码生成');
      const confirmLoading = ref(false);
      const code = ref('');
      const metaModel = reactive({
        projectPath: '',
        packageStyle: 'service',
        jspMode: '',
        jformType: '1',
        tableName_tmp: '',
        ftlDescription: '',
        entityName: '',
        codeTypes: 'controller,service,dao,mapper,entity,vue',
      });
      const model = reactive({});
      const jspModeOptions = ref([]);
      const subTable = reactive({
        dataSource: [],
        columns: [
          {
            title: '子表名',
            key: 'tableName',
            type: JVxeTypes.input,
            disabled: true,
            validateRules: [{ required: true, message: '请输入${title}' }],
          },
          {
            title: '子表实体',
            key: 'entityName',
            type: JVxeTypes.input,
            validateRules: [{ required: true, message: '请输入${title}' }],
          },
          {
            title: '功能说明',
            key: 'ftlDescription',
            type: JVxeTypes.input,
            validateRules: [{ required: true, message: '请输入${title}' }],
          },
        ],
      });
      const showSubTable = computed(() => subTable.dataSource.length > 0);
      const { formSchemas } = useCodeGeneratorFormSchemas(
        props,
        {
          onProjectPathChange,
          onProjectPathSearch,
          jspModeOptions,
        },
        single
      );
      const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
        schemas: formSchemas,
        showActionButtonGroup: false,
        labelAlign: 'right',
      });
      const [registerModal, { closeModal }] = useModalInner(async (data) => {
        await resetFields();
        code.value = data.code;
        confirmLoading.value = false;
        subTable.dataSource = [];
        jspModeOptions.value = [];
        getStoreProjectPath();
        Object.assign(model, metaModel);
        loadData();
      });
      async function loadData() {
        let { main, sub, jspModeList, projectPath } = await defHttp.get({
          url: '/api-online/online/cgform/head/tableInfo',
          params: { code: code.value },
        });
        let jspModeListForVue3 = [];
        for (let mode of jspModeList) {
          const { code: code2, note } = mode;
          if (code2 == 'many');
          else {
            jspModeListForVue3.push({
              label: note,
              value: code2,
            });
          }
        }
        jspModeOptions.value = jspModeListForVue3;
        if (main.isTree == 'Y') {
          model.jspMode = 'tree';
        } else {
          model.jspMode = jspModeListForVue3[0].value;
        }
        single.value = main.tableType == 1;
        title.value = '代码生成【' + main.tableName + '】';
        if (!model.projectPath) {
          model.projectPath = projectPath;
          window.localStorage.setItem(JEECG_ONL_PROJECT_PATH, projectPath);
        }
        model.jformType = main.tableType + '';
        model.tableName_tmp = main.tableName;
        model.ftlDescription = main.tableTxt;
        let entityNameTemp = underLine2CamelCase(main.tableName);
        model.entityName = entityNameTemp.substring(0, 1).toUpperCase() + entityNameTemp.substring(1);
        await nextTick();
        setFieldsValue(model);
        if (sub && sub.length > 0) {
          subTable.dataSource = sub.map((item) => ({
            tableName: item.tableName,
            entityName: getCamelCase(item.tableName),
            ftlDescription: item.tableTxt,
          }));
        }
      }
      const [registerCodeFileListModal, { openModal: openCodeFileListModal }] = useModal();
      async function onSubmit() {
        try {
          const values = await validate();
          let params = Object.assign({}, values, { code: code.value, tableName: values.tableName_tmp });
          if (showSubTable.value) {
            let errMap = await subTableRef.value.validateTable();
            if (errMap) {
              return;
            }
            params.subList = subTableRef.value.getTableData();
          }
          confirmLoading.value = true;
          let res = await codeGen(params);
          openCodeFileListModal(true, {
            codeList: res.codeList,
            pathKey: res.pathKey,
            tableName: values.tableName_tmp,
          });
          closeModal();
        } catch (e) {
          console.error(e);
        } finally {
          confirmLoading.value = false;
        }
      }
      function codeGen(params) {
        return new Promise((resolve, reject) => {
          defHttp.post({ url: '/api-online/online/cgform/api/codeGenerate', params }, { isTransformResponse: false }).then((res) => {
            if (res.success) {
              let codeList = res.data;
              let pathKey = res.msg;
              resolve({
                codeList,
                pathKey,
              });
            } else {
              reject(res.msg);
            }
          });
        });
      }
      function onCancel() {
        closeModal();
      }
      const [registerFileSelectModal, fileSelectModal] = useModal();
      function onProjectPathSearch() {
        fileSelectModal.openModal(true, {});
      }
      function onFileSelect(url) {
        window.localStorage.setItem(JEECG_ONL_PROJECT_PATH, url);
        setFieldsValue({ projectPath: url });
      }
      function getCamelCase(val) {
        let temp = underLine2CamelCase(val);
        return temp.substring(0, 1).toUpperCase() + temp.substring(1);
      }
      function getStoreProjectPath() {
        let path = window.localStorage.getItem(JEECG_ONL_PROJECT_PATH);
        if (path) {
          metaModel.projectPath = path;
        }
      }
      function onProjectPathChange(e) {
        if (e.target.value) window.localStorage.setItem(JEECG_ONL_PROJECT_PATH, e.target.value);
      }
      return {
        title,
        modalWidth,
        confirmLoading,
        subTable,
        showSubTable,
        onSubmit,
        onCancel,
        onFileSelect,
        registerFileSelectModal,
        subTableRef,
        registerForm,
        registerModal,
        registerCodeFileListModal,
      };
    },
  });
</script>
<style scoped></style>
